
<template>
  <div class="containers main-box">
    <div ref="flowCanvas" class="canvas" />
  </div>
</template>
<script>
/* eslint-disable no-unused-expressions */
import { CustomViewer as BpmnViewer } from 'DQBasic-vue-component'
import RewriteRenderer from '../../RewriteRenderer/index'

export default {
  name: 'FlowView',
  props: {
    flowData: {
      type: Object,
      default: () => {}
    }
  },
  data() {
    return {
      bpmnViewer: null
    }
  },
  watch: {
    flowData: {
      handler(newVal) {
        if (Object.keys(newVal).length > 0) {
          // 生成实例
          this.bpmnViewer && this.bpmnViewer.destroy()
          this.bpmnViewer = new BpmnViewer({
            container: this.$refs.flowCanvas,
            height: 'calc(100vh - 200px)',
            additionalModules: [RewriteRenderer]
          })
          this.loadFlowCanvas(newVal)
        }
      },
      immediate: true, // 立即生效
      deep: true // 监听对象或数组的时候，要用到深度监听
    }
  },
  mounted() {
    // this.$nextTick(() => {
    //   this.bpmnViewer && this.bpmnViewer.destroy()
    //   this.bpmnViewer = new BpmnViewer({
    //     container: this.$refs.flowCanvas,
    //     height: 'calc(100vh - 200px)',
    //     additionalModules: [RewriteRenderer]
    //   })
    //   // 0未经过 1已经过 -1不经过
    //   this.loadFlowCanvas({
    //     nodeDataDetails: [
    //       { activityId: 'Event_06bgflo', taskAccess: '1', name: '开始' },
    //       { activityId: 'Activity_1i35jmn', taskAccess: '1', name: '申请' },
    //       { activityId: 'Gateway_1q007p2', taskAccess: '1', name: '条件分支' },
    //       { activityId: 'Activity_1ouojul', taskAccess: '1', name: '审批-true' },
    //       { activityId: 'Activity_1hc10lo', taskAccess: '-1', name: '审批-false' },
    //       { activityId: 'Activity_1vmwc0l', taskAccess: '-1', name: '审批-false11' },
    //       { activityId: 'Activity_1fxcsla', taskAccess: '0', name: '审批-true11' },
    //       { activityId: 'Event_0ure9d2', taskAccess: '1', name: '结束' },
    //       { activityId: 'Flow_1ub73n3', taskAccess: '1', name: '线-开始-申请' },
    //       { activityId: 'Flow_14uw4vp', taskAccess: '1', name: '线-申请-条件分支' },
    //       { activityId: 'Flow_101aq4k', taskAccess: '-1', name: '线-条件-审批false' },
    //       { activityId: 'Flow_0nydmqh', taskAccess: '1', name: '线-条件-审批true' },
    //       { activityId: 'Flow_1tgu3el', taskAccess: '-1', name: '线-审批false-审批false111' },
    //       { activityId: 'Flow_05cke1e', taskAccess: '-1', name: '线-审批false111-结束' },
    //       { activityId: 'Flow_08rg2k9', taskAccess: '0', name: '线-审批true-审批true11' },
    //       { activityId: 'Flow_0j9yf9r', taskAccess: '0', name: '线-审批true11-结束' }
    //     ]
    //   })
    // })
  },
  methods: {
    // 加载流程
    async loadFlowCanvas(flowData) {
      const self = this
      try {
        // const temp = `
        //         <?xml version="1.0" encoding="UTF-8"?>
        // <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:flowable="http://flowable.org/bpmn" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="diagram_Process_1693274848389" targetNamespace="http://www.flowable.org/processdef">
        //   <process id="Process_1695347387714" name="业务流程_1695347387714" isExecutable="true" entrance="1" skipPeople="0" startUser="0" icon="renzhengcishu" categoryId="22">
        //     <startEvent id="Event_06bgflo" name="开始节点">
        //       <outgoing>Flow_1ub73n3</outgoing>
        //     </startEvent>
        //     <endEvent id="Event_0ure9d2" name="结束节点">
        //       <incoming>Flow_05cke1e</incoming>
        //       <incoming>Flow_0j9yf9r</incoming>
        //     </endEvent>
        //     <userTask id="Activity_1i35jmn" name="申请" userTaskType="2">
        //       <extensionElements>
        //         <flowable:properties>
        //           <flowable:property value="1231" name="111" />
        //         </flowable:properties>
        //       </extensionElements>
        //       <incoming>Flow_1ub73n3</incoming>
        //       <outgoing>Flow_14uw4vp</outgoing>
        //     </userTask>
        //     <sequenceFlow id="Flow_1ub73n3" sourceRef="Event_06bgflo" targetRef="Activity_1i35jmn" />
        //     <userTask id="Activity_1ouojul" name="审批-true" userTaskType="1">
        //       <incoming>Flow_0nydmqh</incoming>
        //       <outgoing>Flow_08rg2k9</outgoing>
        //     </userTask>
        //     <exclusiveGateway id="Gateway_1q007p2" name="条件分支">
        //       <incoming>Flow_14uw4vp</incoming>
        //       <outgoing>Flow_101aq4k</outgoing>
        //       <outgoing>Flow_0nydmqh</outgoing>
        //     </exclusiveGateway>
        //     <sequenceFlow id="Flow_14uw4vp" sourceRef="Activity_1i35jmn" targetRef="Gateway_1q007p2" />
        //     <userTask id="Activity_1hc10lo" name="审批-条件false" userTaskType="1">
        //       <incoming>Flow_101aq4k</incoming>
        //       <outgoing>Flow_1tgu3el</outgoing>
        //     </userTask>
        //     <sequenceFlow id="Flow_101aq4k" sourceRef="Gateway_1q007p2" targetRef="Activity_1hc10lo" />
        //     <sequenceFlow id="Flow_0nydmqh" sourceRef="Gateway_1q007p2" targetRef="Activity_1ouojul" />
        //     <userTask id="Activity_1vmwc0l" name="审批false111" userTaskType="1">
        //       <incoming>Flow_1tgu3el</incoming>
        //       <outgoing>Flow_05cke1e</outgoing>
        //     </userTask>
        //     <sequenceFlow id="Flow_1tgu3el" sourceRef="Activity_1hc10lo" targetRef="Activity_1vmwc0l" />
        //     <sequenceFlow id="Flow_05cke1e" sourceRef="Activity_1vmwc0l" targetRef="Event_0ure9d2" />
        //     <userTask id="Activity_1fxcsla" name="审批ture-111" userTaskType="1">
        //       <incoming>Flow_08rg2k9</incoming>
        //       <outgoing>Flow_0j9yf9r</outgoing>
        //     </userTask>
        //     <sequenceFlow id="Flow_08rg2k9" sourceRef="Activity_1ouojul" targetRef="Activity_1fxcsla" />
        //     <sequenceFlow id="Flow_0j9yf9r" sourceRef="Activity_1fxcsla" targetRef="Event_0ure9d2" />
        //   </process>
        //   <bpmndi:BPMNDiagram id="BPMNDiagram_1">
        //     <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1695347387714">
        //       <bpmndi:BPMNShape id="Event_06bgflo_di" bpmnElement="Event_06bgflo">
        //         <omgdc:Bounds x="590" y="130" width="40" height="40" />
        //         <bpmndi:BPMNLabel>
        //           <omgdc:Bounds x="587" y="106" width="44" height="14" />
        //         </bpmndi:BPMNLabel>
        //       </bpmndi:BPMNShape>
        //       <bpmndi:BPMNShape id="Activity_1i35jmn_di" bpmnElement="Activity_1i35jmn">
        //         <omgdc:Bounds x="525" y="230" width="170" height="40" />
        //       </bpmndi:BPMNShape>
        //       <bpmndi:BPMNShape id="Gateway_1q007p2_di" bpmnElement="Gateway_1q007p2" isMarkerVisible="true">
        //         <omgdc:Bounds x="585" y="325" width="50" height="50" />
        //         <bpmndi:BPMNLabel>
        //           <omgdc:Bounds x="531" y="343" width="44" height="14" />
        //         </bpmndi:BPMNLabel>
        //       </bpmndi:BPMNShape>
        //       <bpmndi:BPMNShape id="Activity_1hc10lo_di" bpmnElement="Activity_1hc10lo">
        //         <omgdc:Bounds x="525" y="425" width="170" height="40" />
        //         <bpmndi:BPMNLabel />
        //       </bpmndi:BPMNShape>
        //       <bpmndi:BPMNShape id="Activity_1ouojul_di" bpmnElement="Activity_1ouojul">
        //         <omgdc:Bounds x="785" y="330" width="170" height="40" />
        //         <bpmndi:BPMNLabel />
        //       </bpmndi:BPMNShape>
        //       <bpmndi:BPMNShape id="Event_0ure9d2_di" bpmnElement="Event_0ure9d2">
        //         <omgdc:Bounds x="590" y="640" width="40" height="40" />
        //         <bpmndi:BPMNLabel>
        //           <omgdc:Bounds x="588" y="690" width="44" height="14" />
        //         </bpmndi:BPMNLabel>
        //       </bpmndi:BPMNShape>
        //       <bpmndi:BPMNShape id="Activity_1vmwc0l_di" bpmnElement="Activity_1vmwc0l">
        //         <omgdc:Bounds x="525" y="525" width="170" height="40" />
        //         <bpmndi:BPMNLabel />
        //       </bpmndi:BPMNShape>
        //       <bpmndi:BPMNShape id="Activity_1fxcsla_di" bpmnElement="Activity_1fxcsla">
        //         <omgdc:Bounds x="785" y="500" width="170" height="40" />
        //         <bpmndi:BPMNLabel />
        //       </bpmndi:BPMNShape>
        //       <bpmndi:BPMNEdge id="Flow_1ub73n3_di" bpmnElement="Flow_1ub73n3">
        //         <di:waypoint x="610" y="170" />
        //         <di:waypoint x="610" y="230" />
        //       </bpmndi:BPMNEdge>
        //       <bpmndi:BPMNEdge id="Flow_14uw4vp_di" bpmnElement="Flow_14uw4vp">
        //         <di:waypoint x="610" y="270" />
        //         <di:waypoint x="610" y="325" />
        //       </bpmndi:BPMNEdge>
        //       <bpmndi:BPMNEdge id="Flow_101aq4k_di" bpmnElement="Flow_101aq4k">
        //         <di:waypoint x="610" y="375" />
        //         <di:waypoint x="610" y="425" />
        //       </bpmndi:BPMNEdge>
        //       <bpmndi:BPMNEdge id="Flow_0nydmqh_di" bpmnElement="Flow_0nydmqh">
        //         <di:waypoint x="635" y="350" />
        //         <di:waypoint x="785" y="350" />
        //       </bpmndi:BPMNEdge>
        //       <bpmndi:BPMNEdge id="Flow_1tgu3el_di" bpmnElement="Flow_1tgu3el">
        //         <di:waypoint x="610" y="465" />
        //         <di:waypoint x="610" y="525" />
        //       </bpmndi:BPMNEdge>
        //       <bpmndi:BPMNEdge id="Flow_05cke1e_di" bpmnElement="Flow_05cke1e">
        //         <di:waypoint x="610" y="565" />
        //         <di:waypoint x="610" y="640" />
        //       </bpmndi:BPMNEdge>
        //       <bpmndi:BPMNEdge id="Flow_08rg2k9_di" bpmnElement="Flow_08rg2k9">
        //         <di:waypoint x="870" y="370" />
        //         <di:waypoint x="870" y="500" />
        //       </bpmndi:BPMNEdge>
        //       <bpmndi:BPMNEdge id="Flow_0j9yf9r_di" bpmnElement="Flow_0j9yf9r">
        //         <di:waypoint x="870" y="540" />
        //         <di:waypoint x="870" y="660" />
        //         <di:waypoint x="630" y="660" />
        //       </bpmndi:BPMNEdge>
        //     </bpmndi:BPMNPlane>
        //   </bpmndi:BPMNDiagram>
        // </definitions>
        //         `
        await self.bpmnViewer.importXML(flowData.xmlData)
        // await self.bpmnViewer.importXML(temp)
        this.listenNode()
        self.fitViewport()
        if (flowData.nodeDataDetails !== undefined && flowData.nodeDataDetails.length > 0) {
          self.fillColor(flowData.nodeDataDetails)
        }
      } catch (err) {
        console.error(err.message, err.warnings)
      }
    },
    listenNode() {
      this.bpmnViewer.on('element.click', (e) => {
        this.$emit('getCurrentNode', e)
      })
    },
    // 设置高亮颜色的class
    setNodeColor(nodeCodes, colorClass, canvas) {
      for (let i = 0; i < nodeCodes.length; i++) {
        canvas.addMarker(nodeCodes[i], colorClass)
      }
    },
    // 让图能自适应屏幕
    fitViewport() {
      this.zoom = this.bpmnViewer.get('canvas').zoom('fit-viewport', 'auto')
    },
    // 放大缩小
    zoomViewport(zoomIn = true) {
      this.zoom = this.bpmnViewer.get('canvas').zoom()
      this.zoom += (zoomIn ? 0.1 : -0.1)
      if (this.zoom >= 0.2) this.bpmnViewer.get('canvas').zoom(this.zoom)
    },

    // 设置高亮颜色的
    fillColor(nodeData) {
      const canvas = this.bpmnViewer.get('canvas')
      this.bpmnViewer.getDefinitions().rootElements[0].flowElements.forEach((n) => {
        const completeTask = nodeData.find((m) => m.activityId === n.id)
        const todoTask = nodeData.find((m) => !m.taskAccess)
        const endTask = nodeData[nodeData.length - 1]
        const setColor = (id, taskAccess) => {
          const curActive = this.bpmnViewer.getDefinitions().rootElements[0].flowElements.find((n1) => n1.id === id)
          // 不控制开始和结束的样式
          if (curActive && (curActive.$type === 'bpmn:EndEvent' || curActive.$type === 'bpmn:StartEvent')) { return }
          // 0未经过 1已经过 -1不经过
          const obj = {
            0: 'highlight-todo', 1: 'highlight', '-1': 'not-highlight', 2: 'active-highlight'
          }
          canvas.addMarker(id, obj[taskAccess])
        }
        if (n.$type === 'bpmn:UserTask') {
          if (completeTask) {
            setColor(n.id, completeTask.taskAccess)
            n.outgoing?.forEach((nn) => {
              const targetTask = nodeData.find((m) => m.activityId === nn.targetRef.id)
              if (targetTask) {
                if (todoTask && completeTask.activityId === todoTask.activityId && !todoTask.taskAccess) {
                  setColor(nn.id, todoTask.taskAccess)
                  setColor(nn.targetRef.id, todoTask.taskAccess)
                } else {
                  setColor(nn.id, targetTask.taskAccess)
                  setColor(nn.targetRef.id, targetTask.taskAccess)
                }
              }
            })
          }
        }
        // 排他网关
        else if (n.$type === 'bpmn:ExclusiveGateway') {
          if (completeTask) {
            setColor(n.id, completeTask.taskAccess)
            n.outgoing?.forEach((nn) => {
              const targetTask = nodeData.find((m) => m.activityId === nn.targetRef.id)
              if (targetTask) {
                setColor(nn.id, targetTask.taskAccess)
                setColor(nn.targetRef.id, targetTask.taskAccess)
              }
            })
          }
        }
        // 并行网关
        else if (n.$type === 'bpmn:ParallelGateway') {
          if (completeTask) {
            setColor(n.id, completeTask.taskAccess)
            n.outgoing?.forEach((nn) => {
              const targetTask = nodeData.find((m) => m.activityId === nn.targetRef.id)
              if (targetTask) {
                setColor(nn.id, targetTask.taskAccess)
                setColor(nn.targetRef.id, targetTask.taskAccess)
              }
            })
          }
        } else if (n.$type === 'bpmn:StartEvent') { // 不控制开始和结束的样式
          // canvas.addMarker(n.id, 'noneSty')
          // n.outgoing.forEach(nn => {
          //   const completeTask = nodeData.find(m => m.activityId === nn.targetRef.id)
          //   if (completeTask) {
          //     canvas.addMarker(nn.id, 'highlight')
          //     canvas.addMarker(n.id, 'highlight')
          //     return
          //   }
          // })
        } else if (n.$type === 'bpmn:SequenceFlow') {
          setColor(n.id, completeTask.taskAccess)
        } else if (n.$type === 'bpmn:EndEvent') {
          // if (endTask.activityId === n.id && endTask.taskAccess) {
          // canvas.addMarker(n.id, 'noneSty')
          //   return
          // }
        }
      })
    }
  }
}
</script>
<style lang="scss">
$complete-bg-color:#58B0A6; // 已执行
$not-complete-bg-color:#606266; // 未执行
$not-bg-color:#C0C4CC; // 不执行了
  .bjs-powered-by {
    display: none;
  }
  .view-mode {
    .el-header, .el-aside, .djs-palette, .bjs-powered-by {
      display: none;
    }
    .el-loading-mask {
      background-color: initial;
    }
    .el-loading-spinner {
      display: none;
    }
  }
  .containers {
    // background-color: #ffffff;
    width: 100%;
    height: 100%;
    .canvas {
      width: 100%;
      height: 100%;
    }
    .panel {
      position: absolute;
      right: 0;
      top: 50px;
      width: 300px;
    }
    .load {
      margin-right: 10px;
    }
    .el-form-item__label{
      font-size: 13px;
    }

    .djs-palette{
      left: 0px!important;
      top: 0px;
      border-top: none;
    }

    .djs-container svg {
      min-height: 650px;
    }
    // 已执行
    .highlight.djs-shape .djs-visual > :nth-child(1) {
      fill: $complete-bg-color !important;
      stroke: $complete-bg-color !important;
      fill-opacity: 0.1 !important;
    }
    .highlight.djs-shape .djs-visual > :nth-child(2) {
      fill: $complete-bg-color !important;
    }
    .highlight.djs-shape .djs-visual > path {
      fill: $complete-bg-color !important;
      // fill-opacity: 0.1 !important;
      stroke: $complete-bg-color !important;
    }
    .highlight.djs-connection > .djs-visual > path {
      stroke: $complete-bg-color !important;
    }
    // 还未执行
    .highlight-todo.djs-connection > .djs-visual > path {
      stroke: $not-complete-bg-color !important;
      // stroke-dasharray: 4px !important;
      fill-opacity: 0.1 !important;
    }
    .highlight-todo.djs-shape .djs-visual > path {
      fill: #727C90 !important;
      // fill-opacity: 0.1 !important;
      stroke: #727C90 !important;
    }
    .highlight-todo.djs-shape .djs-visual > :nth-child(1) {
      fill: #fff !important;
      stroke: $not-complete-bg-color !important;
      // stroke-dasharray: 4px !important;
      fill-opacity:0.1 !important;
    }
    // 正在执行
    .active-highlight.djs-shape .djs-visual > :nth-child(1) {
      fill: #EAEFFF !important;
      // stroke: #3461FF !important;
      // stroke-dasharray: 4px !important;
      // fill-opacity:0.1 !important;
    }
    .active-highlight.djs-shape .djs-visual > path {
      fill: #3461FF !important;
      // fill-opacity: 0.1 !important;
      // stroke: #727C90 !important;
    }
    // 不执行了
    .not-highlight.djs-shape .djs-visual > :nth-child(1) {
      fill: $not-bg-color !important;
      stroke: $not-bg-color !important;
      fill-opacity: 0.1 !important;
    }
    .not-highlight.djs-shape .djs-visual > :nth-child(2) {
      fill: $not-bg-color !important;
    }
    .not-highlight.djs-shape .djs-visual > path {
      fill: $not-bg-color !important;
      // fill-opacity: 0.1 !important;
      stroke: $not-bg-color !important;
    }
    .not-highlight.djs-connection > .djs-visual > path {
      stroke: $not-bg-color !important;
    }
    .overlays-div {
      font-size: 10px;
      color: red;
      width: 100px;
      top: -20px !important;
    }
  }
</style>
